/*
 * Copyright (C) 2016 Lokiy(liulongke@gmail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  　　　　http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.lokiy.core.activity

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.MotionEvent
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import com.lokiy.core.R
import com.lokiy.core.RequestForResult
import com.lokiy.core.fragment.BasicFragment
import com.lokiy.core.internal.DefaultStore
import com.lokiy.core.internal.IStore

/**
 * CommonActivity
 * lokiy
 * 2020-12-14
 */
class CommonActivity : AppCompatActivity(), RequestForResult, IStore by DefaultStore() {

    private lateinit var mFragment: Fragment

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        registerRequest()
        @Suppress("UNCHECKED_CAST") val clazz = intent.getSerializableExtra("_FRAGMENT_CLASS") as Class<out Fragment>
        val layout = FrameLayout(this)
        layout.id = R.id.container
        layout.layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
        setContentView(layout)
        val supportFragmentManager = supportFragmentManager
        val tag = clazz.simpleName
        if (supportFragmentManager.findFragmentByTag(tag)?.also { mFragment = it } == null) {
            mFragment = supportFragmentManager.fragmentFactory.instantiate(classLoader, clazz.name)
            mFragment.arguments = intent.extras
            supportFragmentManager.beginTransaction().add(R.id.container, mFragment, tag).commitNow()
        }
    }

    override fun onBackPressed() {
        val lastFragment = supportFragmentManager.fragments.lastOrNull()
        if (lastFragment is BasicFragment && lastFragment.onBackPressed()) {
            return
        }
        super.onBackPressed()
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        val lastFragment = supportFragmentManager.fragments.lastOrNull()
        return (lastFragment is BasicFragment && lastFragment.onTouchEvent(event)) || super.onTouchEvent(event)
    }

    override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
        val lastFragment = supportFragmentManager.fragments.lastOrNull()
        return (lastFragment is BasicFragment && lastFragment.dispatchTouchEvent(ev)) || super.dispatchTouchEvent(ev)
    }

    companion object {

        @JvmStatic
        fun getIntent(context: Context?, clazz: Class<*>, intent: Intent?) = Intent(context, CommonActivity::class.java).apply {
            putExtra("_FRAGMENT_CLASS", clazz)
            if (intent != null) {
                putExtras(intent)
            }

        }

        @JvmStatic
        fun startActivity(context: Context?, clazz: Class<out Fragment?>?, bundle: Bundle?) {
            startActivityForResult(context, clazz, bundle, -1)
        }

        @JvmStatic
        fun startActivityForResult(context: Context?, clazz: Class<out Fragment?>?, bundle: Bundle?, requestCode: Int) {
            if (context is Activity) {
                val intent = Intent(context, CommonActivity::class.java)
                if (bundle != null) {
                    intent.putExtras(bundle)
                }
                intent.putExtra("_FRAGMENT_CLASS", clazz)
                if (requestCode != 0 && context is CommonActivity) {
                    val fragments = context.supportFragmentManager.fragments
                    var fragment: Fragment? = null
                    for (i in fragments.indices.reversed()) {
                        val f = fragments[i]
                        if (f is RequestForResult) {
                            fragment = f
                            break
                        }
                    }
                    if (fragment != null) {
                        fragment.startActivityForResult(intent, requestCode)
                    } else {
                        (context as Activity).startActivityForResult(intent, requestCode)
                    }
                } else {
                    context.startActivityForResult(intent, requestCode)
                }
            }
        }

        @JvmStatic
        fun startActivityForResult(fragment: Fragment, clazz: Class<out Fragment?>?, bundle: Bundle?, requestCode: Int) {
            val intent = Intent(fragment.context, CommonActivity::class.java)
            if (bundle != null) {
                intent.putExtras(bundle)
            }
            intent.putExtra("_FRAGMENT_CLASS", clazz)
            fragment.startActivityForResult(intent, requestCode)
        }
    }
}